From e568bde96e9f15bbd8fe571ad719ccb0491da34d Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Mon, 24 Nov 2025 00:05:33 +0100 Subject: [PATCH] odhcpd: remove OAF_BROKEN_HOSTNAME MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A bool is quite a bit more ergonomic (as the diff for this commit shows). Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/331 Signed-off-by: Álvaro Fernández Rojas --- src/config.c | 23 +++++++++++++++-------- src/dhcpv4.c | 10 ++++------ src/dhcpv6-ia.c | 10 ++++------ src/odhcpd.c | 8 ++++---- src/odhcpd.h | 9 +++++---- src/statefiles.c | 16 ++++++++-------- src/ubus.c | 2 +- 7 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/config.c b/src/config.c index f5773dc..0e588b6 100644 --- a/src/config.c +++ b/src/config.c @@ -673,8 +673,11 @@ int config_set_lease_cfg_from_blobmsg(struct blob_attr *ba) } if ((c = tb[LEASE_CFG_ATTR_NAME])) { + if (!odhcpd_hostname_valid(blobmsg_get_string(c))) + goto err; + lease_cfg->hostname = strdup(blobmsg_get_string(c)); - if (!lease_cfg->hostname || !odhcpd_valid_hostname(lease_cfg->hostname)) + if (!lease_cfg->hostname) goto err; } @@ -1767,23 +1770,27 @@ static void lease_cfg_delete_dhcpv6_leases(struct lease_cfg *lease_cfg) static void lease_cfg_update_leases(struct lease_cfg *lease_cfg) { - struct dhcpv4_lease *a4 = lease_cfg->dhcpv4_lease; + struct dhcpv4_lease *lease4 = lease_cfg->dhcpv4_lease; struct dhcpv6_lease *lease6; - if (a4) { - free(a4->hostname); - a4->hostname = NULL; + if (lease4) { + free(lease4->hostname); + lease4->hostname = NULL; - if (lease_cfg->hostname) - a4->hostname = strdup(lease_cfg->hostname); + if (lease_cfg->hostname) { + lease4->hostname = strdup(lease_cfg->hostname); + lease4->hostname_valid = true; + } } list_for_each_entry(lease6, &lease_cfg->dhcpv6_leases, lease_cfg_list) { free(lease6->hostname); lease6->hostname = NULL; - if (lease_cfg->hostname) + if (lease_cfg->hostname) { lease6->hostname = strdup(lease_cfg->hostname); + lease6->hostname_valid = true; + } lease6->leasetime = lease_cfg->leasetime; } diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 5afeb91..c41c13d 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -636,8 +636,10 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg req_msg, const uint8_t *re if (lease_cfg) { lease->flags |= OAF_STATIC; - if (lease_cfg->hostname) + if (lease_cfg->hostname) { lease->hostname = strdup(lease_cfg->hostname); + lease->hostname_valid = true; + } lease_cfg->dhcpv4_lease = lease; lease->lease_cfg = lease_cfg; @@ -667,11 +669,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg req_msg, const uint8_t *re lease->hostname = new_name; memcpy(lease->hostname, req_hostname, req_hostname_len); lease->hostname[req_hostname_len] = 0; - - if (odhcpd_valid_hostname(lease->hostname)) - lease->flags &= ~OAF_BROKEN_HOSTNAME; - else - lease->flags |= OAF_BROKEN_HOSTNAME; + lease->hostname_valid = odhcpd_hostname_valid(lease->hostname); } } diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 34b088b..cc27e5b 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -1173,8 +1173,10 @@ proceed: if (lease_cfg && assigned) { a->flags |= OAF_STATIC; - if (lease_cfg->hostname) + if (lease_cfg->hostname) { a->hostname = strdup(lease_cfg->hostname); + a->hostname_valid = true; + } if (lease_cfg->leasetime) a->leasetime = lease_cfg->leasetime; @@ -1244,11 +1246,7 @@ proceed: a->hostname = tmp; memcpy(a->hostname, hostname, hostname_len); a->hostname[hostname_len] = 0; - - if (odhcpd_valid_hostname(a->hostname)) - a->flags &= ~OAF_BROKEN_HOSTNAME; - else - a->flags |= OAF_BROKEN_HOSTNAME; + a->hostname_valid = odhcpd_hostname_valid(a->hostname); } } a->accept_fr_nonce = accept_reconf; diff --git a/src/odhcpd.c b/src/odhcpd.c index 3ba94a2..00ca42d 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -756,14 +756,13 @@ int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *p return 0; } -bool odhcpd_valid_hostname(const char *name) +bool odhcpd_hostname_valid(const char *name) { -#define MAX_LABEL 63 const char *c, *label, *label_end; int label_sz = 0; for (c = name, label_sz = 0, label = name, label_end = name + strcspn(name, ".") - 1; - *c && label_sz <= MAX_LABEL; c++) { + *c && label_sz <= DNS_MAX_LABEL_LEN; c++) { if ((*c >= '0' && *c <= '9') || (*c >= 'A' && *c <= 'Z') || (*c >= 'a' && *c <= 'z')) { @@ -771,6 +770,7 @@ bool odhcpd_valid_hostname(const char *name) continue; } + /* FIXME: underscore is not allowed in RFC 1035, RFC 1123? */ if ((*c == '_' || *c == '-') && c != label && c != label_end) { label_sz++; continue; @@ -788,5 +788,5 @@ bool odhcpd_valid_hostname(const char *name) return false; } - return (label_sz && label_sz <= MAX_LABEL ? true : false); + return (label_sz && label_sz <= DNS_MAX_LABEL_LEN ? true : false); } diff --git a/src/odhcpd.h b/src/odhcpd.h index 6265c94..d4b87cf 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -193,9 +193,8 @@ enum odhcpd_assignment_flags { OAF_TENTATIVE = (1 << 0), OAF_BOUND = (1 << 1), OAF_STATIC = (1 << 2), - OAF_BROKEN_HOSTNAME = (1 << 3), - OAF_DHCPV6_NA = (1 << 4), - OAF_DHCPV6_PD = (1 << 5), + OAF_DHCPV6_NA = (1 << 3), + OAF_DHCPV6_PD = (1 << 4), }; /* 2-byte type + 128-byte DUID, RFC8415, §11.1 */ @@ -260,6 +259,7 @@ struct dhcpv4_lease { unsigned int flags; // OAF_* time_t valid_until; // CLOCK_MONOTONIC time, 0 = inf char *hostname; // client hostname + bool hostname_valid; // is the hostname one or more valid DNS labels? size_t hwaddr_len; // hwaddr length uint8_t hwaddr[ETH_ALEN]; // hwaddr (only MAC supported) @@ -302,6 +302,7 @@ struct dhcpv6_lease { unsigned int flags; uint32_t leasetime; char *hostname; + bool hostname_valid; // is the hostname one or more valid DNS labels? uint32_t iaid; uint16_t duid_len; @@ -565,7 +566,7 @@ typedef void (*odhcpd_enum_addr6_cb_t)(struct dhcpv6_lease *lease, void odhcpd_enum_addr6(struct interface *iface, struct dhcpv6_lease *lease, time_t now, odhcpd_enum_addr6_cb_t func, void *arg); int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix); -bool odhcpd_valid_hostname(const char *name); +bool odhcpd_hostname_valid(const char *name); int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite); struct lease_cfg *config_find_lease_cfg_by_duid_and_iaid(const uint8_t *duid, diff --git a/src/statefiles.c b/src/statefiles.c index 0c82a6d..20664f6 100644 --- a/src/statefiles.c +++ b/src/statefiles.c @@ -55,7 +55,7 @@ static bool statefiles_write_host6(struct write_ctxt *ctxt, struct dhcpv6_lease { char ipbuf[INET6_ADDRSTRLEN]; - if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME || !(lease->flags & OAF_DHCPV6_NA)) + if (!lease->hostname || !lease->hostname_valid || !(lease->flags & OAF_DHCPV6_NA)) return false; if (ctxt->fp) { @@ -78,7 +78,7 @@ static bool statefiles_write_host4(struct write_ctxt *ctxt, struct dhcpv4_lease { char ipbuf[INET_ADDRSTRLEN]; - if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME) + if (!lease->hostname || !lease->hostname_valid) return false; if (ctxt->fp) { @@ -165,7 +165,7 @@ static void statefiles_write_state6_addr(struct dhcpv6_lease *lease, struct in6_ struct write_ctxt *ctxt = (struct write_ctxt *)arg; char ipbuf[INET6_ADDRSTRLEN]; - if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME) && lease->flags & OAF_DHCPV6_NA) { + if (lease->hostname && lease->hostname_valid && lease->flags & OAF_DHCPV6_NA) { md5_hash(addr, sizeof(*addr), &ctxt->md5); md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5); } @@ -188,8 +188,8 @@ static void statefiles_write_state6(struct write_ctxt *ctxt, struct dhcpv6_lease fprintf(ctxt->fp, "# %s %s %x %s%s %" PRId64 " %" PRIx64 " %" PRIu8, ctxt->iface->ifname, duidbuf, ntohl(lease->iaid), - (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "", - (lease->hostname ? lease->hostname : "-"), + lease->hostname_valid ? "" : "broken\\x20", + lease->hostname ? lease->hostname : "-", (lease->valid_until > ctxt->now ? (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) : (INFINITE_VALID(lease->valid_until) ? -1 : 0)), @@ -210,7 +210,7 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease char hexhwaddr[sizeof(lease->hwaddr) * 2 + 1]; char ipbuf[INET6_ADDRSTRLEN]; - if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME)) { + if (lease->hostname && lease->hostname_valid) { md5_hash(&lease->ipv4, sizeof(lease->ipv4), &ctxt->md5); md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5); } @@ -225,8 +225,8 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease fprintf(ctxt->fp, "# %s %s ipv4 %s%s %" PRId64 " %x 32 %s/32\n", ctxt->iface->ifname, hexhwaddr, - (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "", - (lease->hostname ? lease->hostname : "-"), + lease->hostname_valid ? "" : "broken\\x20", + lease->hostname ? lease->hostname : "-", (lease->valid_until > ctxt->now ? (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) : (INFINITE_VALID(lease->valid_until) ? -1 : 0)), diff --git a/src/ubus.c b/src/ubus.c index 2f2f206..eebedf0 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -65,7 +65,7 @@ static int handle_dhcpv4_leases(struct ubus_context *ctx, _o_unused struct ubus_ if (c->flags & OAF_STATIC) blobmsg_add_string(&b, NULL, "static"); - if (c->flags & OAF_BROKEN_HOSTNAME) + if (!c->hostname_valid) blobmsg_add_string(&b, NULL, "broken-hostname"); blobmsg_close_array(&b, m); -- 2.30.2